<template>
  <div class="beidou-grid-container">
    <div id="cesiumContainer"></div>
    <div class="controls">
      <div class="control-item">
        <label>当前级别：</label>
        <span>{{ currentLevel }}级</span>
      </div>
      <div class="control-item">
        <label>显示编码：</label>
        <input type="checkbox" v-model="showGridCode" />
      </div>
      <div class="control-item">
        <label>隔离模式：</label>
        <input type="checkbox" v-model="isIsolationMode" />
      </div>
      <div class="control-item">
        <label>显示级别：</label>
        <select v-model="minDisplayLevel">
          <option v-for="i in 10" :key="i" :value="i">{{ i }}级</option>
        </select>
      </div>
      <div class="control-item">
        <label>网格样式：</label>
        <select v-model="gridStyle">
          <option value="solid">实心</option>
          <option value="wireframe">线框</option>
        </select>
      </div>
      <div class="control-item">
        <label>高度比例：</label>
        <input type="range" v-model="heightScale" min="0.1" max="2" step="0.1" />
        <span>{{ heightScale }}x</span>
      </div>
    </div>
  </div>
</template>

<script>
import * as Cesium from "cesium";
import { onMounted, ref, watch, onUnmounted } from "vue";
import { BeidouGridCode } from "../utils/BeidouGridCode";
import "../Widgets/widgets.css";
Cesium.Ion.defaultAccessToken =
  "";
//3.设置静态资源路径
window.CESIUM_BASE_URL = "/";

export default {
  name: "BeidouGrid",
  setup() {
    const viewer = ref(null);
    const currentLevel = ref(1);
    const showGridCode = ref(false);
    const isIsolationMode = ref(false);
    const minDisplayLevel = ref(1);
    const gridStyle = ref('wireframe');
    const heightScale = ref(1.0);
    const gridEntities = ref(new Map());

    // 网格级别常量定义
    const GRID_LEVELS = {
      LEVEL_1: { lon: 6, lat: 4, height: 10000000, maxGrids: 1000 },
      LEVEL_2: { lon: 30/60, lat: 30/60, height: 5000000, maxGrids: 2000 },
      LEVEL_3: { lon: 15/60, lat: 10/60, height: 1000000, maxGrids: 4000 },
      LEVEL_4: { lon: 1/60, lat: 1/60, height: 500000, maxGrids: 8000 },
      LEVEL_5: { lon: 4/3600, lat: 4/3600, height: 100000, maxGrids: 10000 },
      LEVEL_6: { lon: 2/3600, lat: 2/3600, height: 50000, maxGrids: 15000 },
      LEVEL_7: { lon: 1/(3600*4), lat: 1/(3600*4), height: 10000, maxGrids: 20000 },
      LEVEL_8: { lon: 1/(3600*32), lat: 1/(3600*32), height: 5000, maxGrids: 25000 },
      LEVEL_9: { lon: 1/(3600*256), lat: 1/(3600*256), height: 1000, maxGrids: 30000 },
      LEVEL_10: { lon: 1/(3600*2048), lat: 1/(3600*2048), height: 500, maxGrids: 35000 }
    };

    // 中国区域边界
    const CHINA_BOUNDS = {
      west: 72.0,
      east: 138.0,
      south: 16.0,
      north: 56.0
    };

    // LOD配置
    const LOD_CONFIG = {
      LEVEL_1: { distance: 20000000, subdivisions: 1 },
      LEVEL_2: { distance: 10000000, subdivisions: 2 },
      LEVEL_3: { distance: 5000000, subdivisions: 4 },
      LEVEL_4: { distance: 2500000, subdivisions: 8 },
      LEVEL_5: { distance: 1000000, subdivisions: 16 }
    };

    // 初始化Cesium viewer
    const initViewer = async () => {
      viewer.value = new Cesium.Viewer("cesiumContainer", {
        terrainProvider: await Cesium.createWorldTerrainAsync({
          requestWaterMask: true,
          requestVertexNormals: true,
        }),
        baseLayerPicker: true,
        timeline: false,
        animation: false,
        homeButton: false,
        navigationHelpButton: false,
        fullscreenButton: true,
        scene3DOnly: true,
        requestRenderMode: true,
        maximumRenderTimeChange: Infinity,
        imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
          url: "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
        }),
      });

      // 设置初始视角到中国
      viewer.value.camera.flyTo({
        destination: Cesium.Rectangle.fromDegrees(
          CHINA_BOUNDS.west,
          CHINA_BOUNDS.south,
          CHINA_BOUNDS.east,
          CHINA_BOUNDS.north
        ),
        duration: 0
      });

      // 性能优化设置
      const scene = viewer.value.scene;
      scene.globe.enableLighting = true;
      scene.globe.depthTestAgainstTerrain = true;
      scene.globe.maximumScreenSpaceError = 1;
      scene.globe.tileCacheSize = 1000;
      
      // 开启视锥剔除
      scene.cullRequestsWhileMoving = true;
      scene.cull = true;
      scene.fog.enabled = true;
      scene.fog.density = 0.0001;
      scene.fog.screenSpaceErrorFactor = 2.0;

      // 监听相机移动事件，使用防抖
      viewer.value.camera.changed.addEventListener(debounce(updateGrids, 100));
    };

    // 防抖函数
    const debounce = (func, wait) => {
      let timeout;
      return function executedFunction(...args) {
        const later = () => {
          clearTimeout(timeout);
          func(...args);
        };
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
      };
    };

    // 更新加载进度
    const updateLoadProgress = (count) => {
      if (count === 0) {
        // 所有瓦片加载完成，触发一次渲染
        viewer.value.scene.requestRender();
      }
    };

    // 使用Web Worker处理网格计算
    const gridWorker = new Worker(new URL('../workers/gridWorker.js', import.meta.url), { type: 'module' });
    
    // 处理Web Worker消息
    gridWorker.onmessage = (e) => {
      const { grids } = e.data;
      createGridEntities(grids);
    };

    // 创建网格实体的批处理函数
    const createGridEntities = (grids) => {
      return new Promise((resolve) => {
        // 使用requestAnimationFrame进行分批处理
        const batchSize = 100;
        let index = 0;

        function processNextBatch() {
          const end = Math.min(index + batchSize, grids.length);
          const batch = grids.slice(index, end);

          batch.forEach(grid => {
            createGridEntity(grid.lon, grid.lat, grid.level);
          });

          index += batchSize;

          if (index < grids.length) {
            requestAnimationFrame(processNextBatch);
          } else {
            resolve();
          }
        }

        requestAnimationFrame(processNextBatch);
      });
    };

    // 根据相机高度确定网格级别
    const determineGridLevel = (cameraHeight) => {
      for (let i = 1; i <= 10; i++) {
        const level = GRID_LEVELS[`LEVEL_${i}`];
        if (cameraHeight > level.height) {
          return i;
        }
      }
      return 10;
    };

    // 获取当前视图范围
    const getCurrentViewRange = () => {
      const camera = viewer.value.camera;
      const rectangle = viewer.value.camera.computeViewRectangle();
      return {
        west: Cesium.Math.toDegrees(rectangle.west),
        east: Cesium.Math.toDegrees(rectangle.east),
        south: Cesium.Math.toDegrees(rectangle.south),
        north: Cesium.Math.toDegrees(rectangle.north),
      };
    };

    // 生成网格的唯一标识
    const generateGridKey = (lon, lat, level) => {
      return `${level}_${lon.toFixed(6)}_${lat.toFixed(6)}`;
    };

    // 限制纬度范围在有效值内
    const clampLatitude = (lat) => {
      return Math.max(Math.min(lat, 89.9), -89.9);
    };

    // 计算网格高度
    const calculateGridHeight = (level, lat) => {
      const baseHeight = 500000; // 基础高度设为500km
      const latFactor = Math.cos(Cesium.Math.toRadians(lat));
      const levelFactor = Math.pow(2, 10 - level);
      return baseHeight * latFactor * levelFactor * heightScale.value;
    };

    // 创建LOD几何体
    const createLODGeometry = (rectangle, height, lodLevel) => {
      const subdivisions = LOD_CONFIG[`LEVEL_${lodLevel}`].subdivisions;
      
      if (isIsolationMode.value) {
        // 创建立体网格框架
        const positions = [];
        const indices = [];
        
        // 计算网格顶点
        const bottomPoints = [];
        const topPoints = [];
        
        // 底部和顶部网格点
        for (let i = 0; i <= subdivisions; i++) {
          for (let j = 0; j <= subdivisions; j++) {
            const lon = Cesium.Math.lerp(rectangle.west, rectangle.east, i / subdivisions);
            const lat = Cesium.Math.lerp(rectangle.south, rectangle.north, j / subdivisions);
            
            // 底部点
            const bottomCartesian = Cesium.Cartesian3.fromRadians(lon, lat, 0);
            bottomPoints.push(bottomCartesian);
            positions.push(bottomCartesian.x, bottomCartesian.y, bottomCartesian.z);
            
            // 顶部点
            const topCartesian = Cesium.Cartesian3.fromRadians(lon, lat, height);
            topPoints.push(topCartesian);
            positions.push(topCartesian.x, topCartesian.y, topCartesian.z);
          }
        }
        
        // 创建网格线索引
        const rows = subdivisions + 1;
        const cols = subdivisions + 1;
        
        // 水平线
        for (let i = 0; i < rows; i++) {
          for (let j = 0; j < cols - 1; j++) {
            const bottomIdx = i * cols + j;
            indices.push(bottomIdx * 2, (bottomIdx + 1) * 2);
            indices.push(bottomIdx * 2 + 1, (bottomIdx + 1) * 2 + 1);
          }
        }
        
        // 垂直线
        for (let j = 0; j < cols; j++) {
          for (let i = 0; i < rows - 1; i++) {
            const bottomIdx = i * cols + j;
            const topIdx = (i + 1) * cols + j;
            indices.push(bottomIdx * 2, topIdx * 2);
            indices.push(bottomIdx * 2 + 1, topIdx * 2 + 1);
          }
        }
        
        // 垂直连接线
        for (let i = 0; i < rows; i++) {
          for (let j = 0; j < cols; j++) {
            const idx = i * cols + j;
            indices.push(idx * 2, idx * 2 + 1);
          }
        }
        
        return new Cesium.Geometry({
          attributes: {
            position: new Cesium.GeometryAttribute({
              componentDatatype: Cesium.ComponentDatatype.DOUBLE,
              componentsPerAttribute: 3,
              values: new Float64Array(positions)
            })
          },
          indices: new Uint16Array(indices),
          primitiveType: Cesium.PrimitiveType.LINES,
          boundingSphere: Cesium.BoundingSphere.fromVertices(positions)
        });
      } else {
        return new Cesium.RectangleGeometry({
          rectangle: rectangle,
          height: 0,
          vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
          granularity: Cesium.Math.toRadians(1.0 / subdivisions)
        });
      }
    };

    // 确定LOD级别
    const determineLODLevel = (distance) => {
      for (let i = 1; i <= 5; i++) {
        if (distance > LOD_CONFIG[`LEVEL_${i}`].distance) {
          return i;
        }
      }
      return 5;
    };

    // 创建网格实体
    const createGridEntity = (lon, lat, level) => {
      const gridLevel = GRID_LEVELS[`LEVEL_${level}`];
      const key = generateGridKey(lon, lat, level);

      if (gridEntities.value.has(key)) {
        return;
      }

      const entities = [];
      const clampedLat = clampLatitude(lat);
      const clampedEndLat = clampLatitude(lat + gridLevel.lat);

      // 计算动态网格高度
      const gridHeight = calculateGridHeight(level, clampedLat);
      
      // 计算网格中心点
      const centerLon = lon + gridLevel.lon / 2;
      const centerLat = clampLatitude(lat + gridLevel.lat / 2);

      // 检查是否在视锥体内
      const rectangle = Cesium.Rectangle.fromDegrees(
        lon,
        clampedLat,
        lon + gridLevel.lon,
        clampedEndLat
      );

      if (!Cesium.Rectangle.intersection(rectangle, viewer.value.camera.computeViewRectangle())) {
        return;
      }

      if (isIsolationMode.value) {
        // 使用Primitive创建立体网格
        const gridPrimitive = createGridPrimitive(lon, lat, level, gridHeight);
        if (gridPrimitive) {
          viewer.value.scene.primitives.add(gridPrimitive);
          entities.push(gridPrimitive);
        }
      } else {
        // 平面模式使用Entity
        const baseGridEntity = viewer.value.entities.add({
          rectangle: {
            coordinates: rectangle,
            material: Cesium.Color.fromCssColorString('#FFD700').withAlpha(0.1),
            height: 0,
            outline: true,
            outlineColor: Cesium.Color.YELLOW.withAlpha(0.5),
            outlineWidth: 2
          }
        });
        entities.push(baseGridEntity);
      }

      // 添加网格编码标签
      if (showGridCode.value) {
        const gridCode = isIsolationMode.value
          ? BeidouGridCode.generate3DCode(centerLon, centerLat, gridHeight, level)
          : BeidouGridCode.generate2DCode(centerLon, centerLat, level);

        // 使用Billboard替代Label以提高性能
        const labelEntity = viewer.value.entities.add({
          position: Cesium.Cartesian3.fromDegrees(
            centerLon,
            centerLat,
            isIsolationMode.value ? gridHeight : 0
          ),
          billboard: {
            image: createTextCanvas(gridCode),
            verticalOrigin: Cesium.VerticalOrigin.CENTER,
            horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
            scale: 1.0,
            pixelOffset: new Cesium.Cartesian2(0, -10),
            distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
              0,
              gridLevel.height * 2
            ),
            scaleByDistance: new Cesium.NearFarScalar(1000, 1.2, 5000000, 0.5),
            translucencyByDistance: new Cesium.NearFarScalar(1000, 1.0, 5000000, 0.8),
            disableDepthTestDistance: Number.POSITIVE_INFINITY
          }
        });
        entities.push(labelEntity);
      }

      gridEntities.value.set(key, entities);
    };

    // 创建文本画布
    const createTextCanvas = (text) => {
      const canvas = document.createElement('canvas');
      const context = canvas.getContext('2d');
      
      // 设置画布大小，进一步减小尺寸
      canvas.width = 64;
      canvas.height = 16;
      
      // 设置文本样式
      context.fillStyle = 'rgba(0, 0, 0, 0)';
      context.fillRect(0, 0, canvas.width, canvas.height);
      context.font = 'bold 12px Microsoft YaHei';
      context.textAlign = 'center';
      context.textBaseline = 'middle';
      
      // 绘制文本轮廓
      context.strokeStyle = 'black';
      context.lineWidth = 1;
      context.strokeText(text, canvas.width/2, canvas.height/2);
      
      // 绘制文本
      context.fillStyle = 'white';
      context.fillText(text, canvas.width/2, canvas.height/2);
      
      return canvas;
    };

    // 切换隔离模式
    const toggleIsolationMode = () => {
      isIsolationMode.value = !isIsolationMode.value;
      gridEntities.value.clear();
      viewer.value.entities.removeAll();
      updateGrids();
    };

    // 监听编码显示状态变化
    watch(showGridCode, (newValue) => {
      if (newValue) {
        // 延迟创建标签，避免卡顿
        setTimeout(() => {
          cleanupGrids();
          updateGrids();
        }, 100);
      } else {
        cleanupGrids();
        updateGrids();
      }
    });

    // 更新网格显示
    const updateGrids = () => {
      if (!viewer.value) return;

      const cameraHeight = viewer.value.camera.positionCartographic.height;
      const level = determineGridLevel(cameraHeight);
      currentLevel.value = level;

      // 如果当前级别小于最小显示级别，不显示网格
      if (level < minDisplayLevel.value) {
        cleanupGrids();
        return;
      }

      const viewRange = getCurrentViewRange();
      const gridLevel = GRID_LEVELS[`LEVEL_${level}`];

      // 清理不需要的网格
      cleanupGrids(viewRange, level);

      // 计算网格范围
      const startLon = Math.max(
        Math.floor(viewRange.west / gridLevel.lon) * gridLevel.lon,
        CHINA_BOUNDS.west
      );
      const endLon = Math.min(
        Math.ceil(viewRange.east / gridLevel.lon) * gridLevel.lon,
        CHINA_BOUNDS.east
      );
      const startLat = Math.max(
        Math.floor(viewRange.south / gridLevel.lat) * gridLevel.lat,
        CHINA_BOUNDS.south
      );
      const endLat = Math.min(
        Math.ceil(viewRange.north / gridLevel.lat) * gridLevel.lat,
        CHINA_BOUNDS.north
      );

      try {
        // 准备网格数据
        const grids = [];
        for (let lon = startLon; lon < endLon; lon += gridLevel.lon) {
          for (let lat = startLat; lat < endLat; lat += gridLevel.lat) {
            if (lon >= -180 && lon <= 180) {
              const height = calculateGridHeight(level, lat);
              grids.push({ lon, lat, level, height });
            }
          }
        }

        // 批量创建实例
        const instances = createBatchGridInstances(grids);
        
        // 如果有实例要渲染
        if (instances.length > 0) {
          // 创建实例化Primitive
          const primitive = createInstancedPrimitive(instances);
          viewer.value.scene.primitives.add(primitive);
          
          // 存储primitive以便后续清理
          gridEntities.value.set(`batch_${level}`, [primitive]);

          // 创建批量标签（使用防抖）
          if (showGridCode.value) {
            debounce(() => {
              const labelBatch = createBatchLabels(grids);
              if (labelBatch) {
                viewer.value.scene.primitives.add(labelBatch);
                gridEntities.value.set(`labels_${level}`, [labelBatch]);
              }
            }, 100)();
          }
        }
      } catch (error) {
        console.error('Error updating grids:', error);
      }
    };

    // 创建批量标签
    const createBatchLabels = (grids) => {
      const labelBatch = new Cesium.LabelCollection({
        scene: viewer.value.scene
      });

      grids.forEach(({ lon, lat, level, height }) => {
        const centerLon = lon + GRID_LEVELS[`LEVEL_${level}`].lon / 2;
        const centerLat = clampLatitude(lat + GRID_LEVELS[`LEVEL_${level}`].lat / 2);
        
        const gridCode = isIsolationMode.value
          ? BeidouGridCode.generate3DCode(centerLon, centerLat, height, level)
          : BeidouGridCode.generate2DCode(centerLon, centerLat, level);

        labelBatch.add({
          position: Cesium.Cartesian3.fromDegrees(
            centerLon,
            centerLat,
            isIsolationMode.value ? height : 0
          ),
          text: gridCode,
          font: '12px Microsoft YaHei',
          fillColor: Cesium.Color.WHITE,
          outlineColor: Cesium.Color.BLACK,
          outlineWidth: 2,
          style: Cesium.LabelStyle.FILL_AND_OUTLINE,
          verticalOrigin: Cesium.VerticalOrigin.CENTER,
          horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
          pixelOffset: new Cesium.Cartesian2(0, -10),
          scale: 1.0,
          distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
            0,
            GRID_LEVELS[`LEVEL_${level}`].height * 2
          ),
          scaleByDistance: new Cesium.NearFarScalar(1000, 1.2, 5000000, 0.5)
        });
      });

      return labelBatch;
    };

    // 清理不在视图范围内的网格
    const cleanupGrids = (viewRange, level) => {
      const keysToRemove = [];
      gridEntities.value.forEach((entities, key) => {
        if (key.startsWith('batch_') || key.startsWith('labels_')) {
          const gridLevel = parseInt(key.split('_')[1]);
          if (gridLevel !== level) {
            entities.forEach(entity => {
              if (entity instanceof Cesium.Primitive || entity instanceof Cesium.BillboardCollection) {
                viewer.value.scene.primitives.remove(entity);
              }
            });
            keysToRemove.push(key);
          }
        }
      });
      keysToRemove.forEach(key => gridEntities.value.delete(key));
    };

    // 创建批量网格实例
    const createBatchGridInstances = (grids) => {
      const instances = [];

      grids.forEach(({ lon, lat, level, height }) => {
        const rectangle = Cesium.Rectangle.fromDegrees(
          lon,
          clampLatitude(lat),
          lon + GRID_LEVELS[`LEVEL_${level}`].lon,
          clampLatitude(lat + GRID_LEVELS[`LEVEL_${level}`].lat)
        );

        // 检查是否在视锥体内
        if (!Cesium.Rectangle.intersection(rectangle, viewer.value.camera.computeViewRectangle())) {
          return;
        }

        // 根据距离确定LOD级别
        const cameraPosition = viewer.value.camera.position;
        const gridCenter = Cesium.Cartesian3.fromDegrees(
          lon + GRID_LEVELS[`LEVEL_${level}`].lon / 2,
          lat + GRID_LEVELS[`LEVEL_${level}`].lat / 2
        );
        const distance = Cesium.Cartesian3.distance(cameraPosition, gridCenter);
        const lodLevel = determineLODLevel(distance);

        // 创建几何实例
        const instance = new Cesium.GeometryInstance({
          geometry: createLODGeometry(rectangle, height, lodLevel),
          id: `grid_${lon}_${lat}_${level}`,
          attributes: {
            color: new Cesium.ColorGeometryInstanceAttribute(1.0, 0.84, 0.0, isIsolationMode.value ? 0.3 : 0.1)
          }
        });

        instances.push(instance);
      });

      return instances;
    };

    // 创建GPU实例化渲染的Primitive
    const createInstancedPrimitive = (instances) => {
      if (isIsolationMode.value) {
        return new Cesium.Primitive({
          geometryInstances: instances,
          appearance: new Cesium.PerInstanceColorAppearance({
            flat: true,
            translucent: true,
            renderState: {
              depthTest: {
                enabled: true
              },
              depthMask: false,
              blending: Cesium.BlendingState.ALPHA_BLEND,
              lineWidth: 1.0
            }
          }),
          asynchronous: false,
          allowPicking: true,
          releaseGeometryInstances: true,
          compressVertices: true
        });
      } else {
        return new Cesium.Primitive({
          geometryInstances: instances,
          appearance: new Cesium.PerInstanceColorAppearance({
            flat: true,
            translucent: true,
            closed: true,
            renderState: {
              depthTest: {
                enabled: true
              },
              depthMask: false,
              blending: Cesium.BlendingState.ALPHA_BLEND
            }
          }),
          asynchronous: false,
          allowPicking: true,
          releaseGeometryInstances: true,
          compressVertices: true
        });
      }
    };

    // 监听选项变化
    watch([minDisplayLevel, gridStyle, heightScale], () => {
      cleanupGrids();
      updateGrids();
    });

    onMounted(() => {
      initViewer();
    });

    onUnmounted(() => {
      // 清理Worker
      if (gridWorker) {
        gridWorker.terminate();
      }
      
      // 清理所有实体和Primitive
      if (viewer.value) {
        viewer.value.entities.removeAll();
        viewer.value.scene.primitives.removeAll();
      }
    });

    return {
      currentLevel,
      showGridCode,
      isIsolationMode,
      minDisplayLevel,
      gridStyle,
      heightScale,
      toggleIsolationMode,
    };
  },
};
</script>

<style scoped>
.beidou-grid-container {
  width: 100%;
  height: 100%;
  position: relative;
}

#cesiumContainer {
  width: 100%;
  height: 100%;
}

.controls {
  position: absolute;
  top: 10px;
  left: 10px;
  background: rgba(0, 0, 0, 0.7);
  padding: 10px;
  border-radius: 4px;
  color: white;
}

.control-item {
  margin: 5px 0;
}

select,
button {
  margin-left: 5px;
  padding: 2px 5px;
}

button {
  background: #4caf50;
  color: white;
  border: none;
  padding: 5px 10px;
  border-radius: 3px;
  cursor: pointer;
}

button:hover {
  background: #45a049;
}
</style>
